package com.example.demo.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.transaction.annotation.Transactional;

import com.example.demo.user.UserRepository;
import java.util.HashMap;
import java.util.Map;

@Controller // This means that this class is a Controller
@RequestMapping(path = "/user") // This means URL's start with /demo (after Application path)
public class UserController {
    @Autowired // This means to get the bean called userRepository
    // Which is auto-generated by Spring, we will use it to handle the data
    private UserRepository userRepository;

    @GetMapping(path = { "/all" })
    public @ResponseBody Iterable<User> getAllUsers() {
        // This returns a JSON or XML with the users
        return userRepository.findAll();
    }

    @GetMapping(path = { "/", "" })
    public @ResponseBody Iterable<User> getUser(@RequestParam String name) {
        // This returns a JSON or XML with the users
        return userRepository.findByName(name);
    }

    @Transactional
    @PostMapping(path = { "/add", "/", "" }) // Map ONLY POST Requests
    public @ResponseBody String addNewUser(@RequestParam String name, @RequestParam String email) {
        // @ResponseBody means the returned String is the response, not a view name
        // @RequestParam means it is a parameter from the GET or POST request
        Iterable<User> users = userRepository.findForUpdateByName(name);
        for (User user : users) {
            return user.getName() + " exist, change anothername";
        }
        User n = new User();
        n.setName(name);
        n.setEmail(email);
        userRepository.save(n);
        return "Saved\n";
    }

    @Transactional
    @PutMapping(path = { "/", "" })
    public @ResponseBody String putUserAge(@RequestParam String name,
            @RequestParam(required = false, defaultValue = "1") String safe,
            @RequestParam(required = false, defaultValue = "0") String reset) throws InterruptedException {
        // @ResponseBody means the returned String is the response, not a view name
        // @RequestParam means it is a parameter from the GET or POST request
        Iterable<User> users;
        if (!safe.equals("0")) {
            users = userRepository.findForUpdateByName(name);
        } else {
            users = userRepository.findByName(name);
        }

        User user = users.iterator().next();
        if (!reset.equals("0")) {
            user.setAge(0);
        } else {
            int oldAge = user.getAge();
            Thread.sleep(100);
            user.setAge(oldAge + 1);
        }
        userRepository.save(user);
        return user.getName() + ", age: " + user.getAge() + " Saved\n";
    }

    @Transactional
    @DeleteMapping(path = { "/", "" })
    public @ResponseBody HashMap<String, String> delUser(@RequestParam String name) {
        // This returns a JSON or XML with the users
        Iterable<User> users = userRepository.findForUpdateByName(name);
        HashMap<String, String> m = new HashMap<>();

        for (User user : users) {
            userRepository.delete(user);
            m.put("del", name);
        }
        return m;
    }
}